package com.chrray.position.util.wx;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.springframework.http.*;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import java.io.*;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * @author M
 * @date
 */
@Slf4j
public class WxApi {

    public static String getAccessToken(String appId, String appSecret) {
        try{
            //  获取Rest客户端实例
            RestTemplate restTemplate = new RestTemplate();
            String accessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appId + "&secret=" + appSecret;

            //  解决(响应数据可能)中文乱码 的问题
            List<HttpMessageConverter<?>> converterList = restTemplate.getMessageConverters();
            // 移除原来的转换器
            converterList.remove(1);
            // 设置字符编码为utf-8
            HttpMessageConverter<?> converter = new StringHttpMessageConverter(StandardCharsets.UTF_8);
            // 添加新的转换器(注:convert顺序错误会导致失败)
            converterList.add(1, converter);
            restTemplate.setMessageConverters(converterList);
            //  (选择性设置)请求头信息
            // HttpHeaders实现了MultiValueMap接口
            HttpHeaders httpHeaders = new HttpHeaders();
            // 给请求header中添加一些数据
//        httpHeaders.add("JustryDeng", "这是一个大帅哥!");

            //  注:GET请求 创建HttpEntity时,请求体传入null即可
            // 请求体的类型任选即可;只要保证 请求体 的类型与HttpEntity类的泛型保持一致即可
            String httpBody = null;
            HttpEntity<String> httpEntity = new HttpEntity<String>(httpBody, httpHeaders);

            //  URI
            StringBuffer paramsURL = new StringBuffer(accessTokenUrl);
            // 字符数据最好encoding一下;这样一来，某些特殊字符才能传过去(如:flag的参数值就是“&”,不encoding的话,传不过去)

            URI uri = URI.create(paramsURL.toString());

            //  执行请求并返回结果
            // 此处的泛型 对应 响应体数据 类型;即:这里指定响应体的数据装配为String
            ResponseEntity<String> response =
                    restTemplate.exchange(uri, HttpMethod.GET, httpEntity, String.class);

            String s = response.getBody();
            log.info("微信服务通知token："+s);
            JSONObject jsonObject = JSONObject.parseObject(s);

            return jsonObject.getString("access_token");
        }catch (Exception e){
            log.error("获取accessToken异常",e);
            return "";
        }

    }

    public static String sendMessage(String accessToken,String openid,String templateId,String page, String miniProgramState,Map data) {
        try {
            RestTemplate restTemplate = new RestTemplate();
            String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token="+accessToken;

            HttpHeaders  headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            WxSendMessageDto  wxSendMessageDto=new WxSendMessageDto();
            wxSendMessageDto.setAccess_token(accessToken);
            wxSendMessageDto.setTouser(openid);
            wxSendMessageDto.setPage(page);
            wxSendMessageDto.setTemplate_id(templateId);
            wxSendMessageDto.setData(data);
            if(!StringUtils.isEmpty(page)){

                wxSendMessageDto.setMiniprogram_state(miniProgramState);
            }

            log.info( "微信服务通知url:{},内容：{}",url,JSONObject.toJSONString(wxSendMessageDto));
            HttpEntity<String> request = new HttpEntity<String>(JSONObject.toJSONString(wxSendMessageDto), headers);
            ResponseEntity<String> response = restTemplate.postForEntity(url, request, String.class);
            log.info("微信服务通知："+response.toString());
            String s = response.getBody();
            JSONObject jsonObject = JSONObject.parseObject(s);
            return jsonObject.toJSONString();
        }catch (Exception e){
            log.error("发送订阅消息异常",e);
            return "";
        }
    }




    public static String addTemplate(String accessToken,String openid,String templateId,String page,Map data) {
        try {
            RestTemplate restTemplate = new RestTemplate();
            String url = "hhttps://api.weixin.qq.com/wxaapi/newtmpl/addtemplate?access_token="+accessToken;

            HttpHeaders  headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            WxSendMessageDto  wxSendMessageDto=new WxSendMessageDto();
            wxSendMessageDto.setAccess_token(accessToken);
            wxSendMessageDto.setTouser(openid);
            wxSendMessageDto.setPage(page);
            wxSendMessageDto.setTemplate_id(templateId);
            wxSendMessageDto.setData(data);

            System.out.println( JSONObject.toJSONString(wxSendMessageDto));
            HttpEntity<String> request = new HttpEntity<String>(JSONObject.toJSONString(wxSendMessageDto), headers);
            ResponseEntity<String> response = restTemplate.postForEntity(url, request, String.class);
            System.out.println("微信服务通知："+response.toString());
            String s = response.getBody();
            JSONObject jsonObject = JSONObject.parseObject(s);
            return jsonObject.toJSONString();
        }catch (Exception e){
            log.error("发送订阅消息异常",e);
            return "";
        }
    }









    public static String getQrCode(String accessToken,String sceneStr,String page,String path) {

        RestTemplate rest = new RestTemplate();
        InputStream inputStream = null;
        OutputStream outputStream = null;
        String filename="";
        try {
            String url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + accessToken;
            Map<String, Object> param = new HashMap<>();
            //param.put("path", "pages/要跳转小程序的路径")//有限<br>
            param.put("scene", sceneStr);
            param.put("page", page); //无限
            param.put("width", 430);
            param.put("auto_color", false);
            Map<String, Object> line_color = new HashMap<>();
            line_color.put("r", 0);
            line_color.put("g", 0);
            line_color.put("b", 0);
            param.put("line_color", line_color);
            log.info("调用生成微信URL接口传参:" + param);
            MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
            HttpEntity requestEntity = new HttpEntity(JSON.toJSONString(param), headers);
            ResponseEntity<byte[]> entity = rest.exchange(url, HttpMethod.POST, requestEntity, byte[].class, new Object[0]);
            log.info("调用小程序生成微信永久小程序码URL接口返回结果:" + JSONObject.toJSONString(entity.getBody()));
            byte[] result = entity.getBody();
            log.info(Base64.encodeBase64String(result));
            inputStream = new ByteArrayInputStream(result);
            String uuid = UUID.randomUUID().toString().replace("-", "");
            File file = new File(path+"/smallCode/"+uuid+".png");
            filename="/smallCode/"+uuid+".png";

            log.info(path+filename);
            if (!file.exists()) {
                file.createNewFile();
            }
            outputStream = new FileOutputStream(file);
            int len = 0;
            byte[] buf = new byte[1024];
            while ((len = inputStream.read(buf, 0, 1024)) != -1) {
                outputStream.write(buf, 0, len);
            }
            outputStream.flush();
        } catch (Exception e) {
            log.error("调用小程序生成微信永久小程序码URL接口异常", e);
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return filename;
    }
}
